<?php
namespace App\WebSocket;

use App\Storage\Avatar;
use App\Storage\ChatMessageFile;
use App\Storage\ChatMessageMysql;
use App\Storage\OnlineUser;
use App\Storage\OnlineShop;
use App\Storage\ServiceRoleRedis;
use App\Storage\UserShopRelation;
use App\Task\BroadcastTask;
use App\Task\RoomTask;
use App\WebSocket\Actions\Broadcast\BroadcastAdmin;
use App\WebSocket\Actions\User\UserInRoom;
use App\WebSocket\Actions\User\UserOutRoom;
use App\WebSocket\Actions\Room\RoomServer;
use EasySwoole\EasySwoole\Swoole\Task\TaskManager;
use EasySwoole\Utility\Random;

class WebSocketEvents {

    /**
     * 新建一个连接
     * @param \swoole_websocket_server $server
     * @param \swoole_http_request $request
     */
    static function onOpen(\swoole_websocket_server $server, \swoole_http_request $request) {
        $fd = $request->fd;
        Avatar::getInstance()->setAvatar();

        $username = isset($request->get['username']) && !empty($request->get['username']) ? $request->get['username'] : '游客' . Random::character(6);
        $avatar = !empty($request->get['avatar']) ? $request->get['avatar'] : Avatar::getInstance()->getAvatar();// 随机给一个头像
        $shopId = !empty($request->get['shop_id']) ? intval($request->get['shop_id']) : 0;
        $isShop = in_array($request->get['is_shop'],[0,1]) ? intval($request->get['is_shop']) : 0; // 默认普通用户
        $userId = !empty($request->get['user_id']) ? intval($request->get['user_id']) : 0;
        $type = in_array(intval($request->get['type']),[1,2]) ? intval($request->get['type']) : 2; // 默认room 点对点沟通。1是群聊，2是单聊
        $serverType = isset($request->get['server_type']) && in_array(intval($request->get['server_type']),[1,2]) ? intval($request->get['type']) : 1; // 商户客服。1.售后，2售后。默认售前


        if ($isShop === 1) { // 客服进入
            // 插入在线客服表
            OnlineShop::getInstance($shopId)->add($userId,['shopId' => $shopId, 'fd' => $fd, 'last_heartbeat' => time()]);
        } else { // 用户进入
            // 客服列表
            if ($shopId > 0) {
                $serviceRole = ServiceRoleRedis::getInstance($shopId)->get($shopId);
                if (isset($serviceRole) && !empty($serviceRole)) {
                    foreach ($serviceRole as $role) {
                        if ($role['role_id'] == $serverType) {

                            $shopUserId = $role['shop_user_id'];
                            // 先判断客服是否在线。不在线提示用户
                            if ($onlineShop = OnlineShop::getInstance($shopId)->get($shopUserId)) {
                                // 缓存 用户-客服的绑定关系
                                UserShopRelation::getInstance()->set($userId, $fd, $shopId, $shopUserId, $onlineShop['fd']);
                            } else {
                                // 提示用户客服不在线，可以留言。
                                $roomServerMessage = new RoomServer();
                                $roomServerMessage->setContent("{$username}, 您好。当前客服不在线，您可以先留言，客服在线第一时间为您处理哦");
                                $server->push($fd, $roomServerMessage->__toString());
                            }
                            break; // todo: 这里如果有多个售前客服，暂时先取第一个
                        }
                    }
                } else {
                    // 提示用户客服不在线，可以留言。
                    $roomServerMessage = new RoomServer();
                    $roomServerMessage->setContent("{$username}, 您好。商家还未开通客服功能");
                    $server->push($fd, $roomServerMessage->__toString());
                }
            }
        }
        OnlineUser::getInstance()->set($fd, $username, $avatar, $shopId, $isShop, $userId);

        if ($type == 2) {
            if (empty($request->get['is_reconnection']) || $request->get['is_reconnection'] == '0') {

                if ($isShop === 0 ) { // 普通用户发 快捷信息。

                    $roomServerMessage = new RoomServer();
                    $roomServerMessage->setContent("{$username}, 您好。请问您想咨询什么问题呢？");
                    $server->push($fd, $roomServerMessage->__toString());
                } elseif ($isShop === 1) { // 客服，发当前的用户数

                    $roomServerMessage = new RoomServer();
                    $roomServerMessage->setContent("{$username}, 欢迎登录客服系统~");
                    $server->push($fd, $roomServerMessage->__toString());
                }

                // 提取指定的历史消息，当前链接的用户
                if ($shopId > 0) {
                    $lastMessage = ChatMessageMysql::getInstance()->getHistoryMessage($shopId, $userId);
                    if (!empty($lastMessage)) {
                        foreach ($lastMessage as $message) {
                            $server->push($fd,json_encode($message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
                        }
                    }
                }
            }

            // 发送信息。XX进来了
            $userInRoomMessage = new UserInRoom();
            $userInRoomMessage->setInfo(['fd' => $fd, 'username' => $username, 'avatar' => $avatar]);
            TaskManager::async(new RoomTask(['payload' => $userInRoomMessage->__toString(), 'fromFd' => $fd, 'userId' => $userId]));

        } elseif ($type == 1) {
             if (empty($request->get['is_reconnection']) || $request->get['is_reconnection'] == '0') {

                // 发送信息。XX用户登录
                $broadcastAdminMessage = new BroadcastAdmin();
                $broadcastAdminMessage->setContent("{$username}, 您好。请问您想咨询什么问题呢？");
                $server->push($fd, $broadcastAdminMessage->__toString());

                // 提取聊天记录，发给用户
                $lastMessage = ChatMessageFile::getInstance()->readMessage();
                $lastMessage = array_reverse($lastMessage);
                if (!empty($lastMessage)) {
                    foreach ($lastMessage as $message) {
                        $message = json_decode($message,true);
                        if (isset($shopId) && $shopId > 0 && isset($message['shopId']) && $message['shopId'] == $shopId) { // 存在shopId，则房间内广播
                            $message = json_encode($message,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                            $server->push($fd, $message);
                        }
                        if (empty($shopId)) { // 没shopId,全员广播
                            $message = json_encode($message,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                            $server->push($fd, $message);
                        }
                    }
                }
            }
            // 发送广播
            $userInRoomMessage = new UserInRoom();
            $userInRoomMessage->setInfo(['fd' => $fd, 'username' => $username, 'avatar' => $avatar]);
            TaskManager::async(new BroadcastTask(['payload' => $userInRoomMessage->__toString(), 'fromFd' => $fd, 'shopId' => $shopId]));

        }
    }

    /**
     * 连接关闭
     * @param \swoole_server $server
     * @param int $fd
     * @param int $reactorId
     */
    static function onClose(\swoole_server $server, int $fd, int $reactorId) {
        $info = $server->connection_info($fd);
        if (isset($info['websocket_status']) && $info['websocket_status'] !== 0) {
            $user = OnlineUser::getInstance()->get($fd);
            $userId = $user['user_id'];
            //移除用户并通知
            OnlineUser::getInstance()->delete($fd);
            //移除用户客服关系绑定。此操作放在了roomTask,204回调中，避免因为先清除关系导致给客服发送消息找不到客服的情况
//            UserShopRelation::getInstance()->delete($userId);
            //移除客服在线列表
            if ($user['is_shop'] == 1 && !empty($user['shop_id'])) {
                OnlineShop::getInstance($user['shop_id'])->delete($userId);
            }
            $message = new UserOutRoom();
            $message->setUserFd($fd);
            TaskManager::async(new RoomTask(['payload' => $message->__toString(), 'fromFd' => $fd, 'userId' => $userId]));
        }
    }

}